package com.hxgz.steel.controller.portal;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.demo.trade.config.Configs;
import com.google.common.collect.Maps;
import com.hxgz.steel.common.Const;
import com.hxgz.steel.common.ResponseCode;
import com.hxgz.steel.common.ServerResponse;
import com.hxgz.steel.domain.Order;
import com.hxgz.steel.domain.User;
import com.hxgz.steel.dto.AddOrderFormDto;
import com.hxgz.steel.dto.NewOrderAskBuyPayDto;
import com.hxgz.steel.dto.PayOrderItemDto;
import com.hxgz.steel.service.NewOrderService;
import com.hxgz.steel.service.OrderService;
import com.hxgz.steel.service.ProductService;
import com.hxgz.steel.util.IpUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

import java.util.Iterator;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@Api(tags = "OrderController", description = "前台-订单、支付 相关")
@RestController
@RequestMapping("order")
@Slf4j
public class OrderController {

  @Autowired
  private OrderService orderService;
  @Autowired
  private NewOrderService newOrderService;
  @Autowired
  private ProductService productService;

  @RequestMapping(value = "pay.do", method = RequestMethod.POST)
  @ApiOperation("支付")
  public ServerResponse pay(HttpServletRequest httpServletRequest,
      @ApiParam("订单号") @RequestParam String orderNo, HttpServletRequest request) {
    User user = Const.checkUserLogin(httpServletRequest);
    if (user == null) {
      return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(),
          ResponseCode.NEED_LOGIN.getDesc());
    }
    String path = request.getSession().getServletContext().getRealPath("upload");
    String ip = IpUtils.getIpAddr(request);
    try {
      return orderService.pay(orderNo, user.getId(), path, ip);
    } catch (Exception e) {
      return ServerResponse.createBySuccessMessage("支付异常");
    }
  }

  @RequestMapping(value = "payForEx.do", method = RequestMethod.POST)
  @ApiOperation("根据Excel支付接口")
  public ServerResponse payForEx(HttpServletRequest httpServletRequest,
      @RequestBody AddOrderFormDto addOrderFormDto) {
    User user = Const.checkUserLogin(httpServletRequest);
    if (user == null) {
      return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(),
          ResponseCode.NEED_LOGIN.getDesc());
    }
    /**
     * 地址校验
     */
    Long addressId = addOrderFormDto.getAddressId();
    if (addressId == null || addressId == 0) {
      return ServerResponse.createByErrorMessage("地址不能为空");
    }
    /**
     * 校验quotation_id是否被多次使用
     */
    Integer count = orderService.checkQuotationId(addOrderFormDto.getQuotationId());
    if (count != 0) {
      return ServerResponse.createByErrorMessage("不能重复提交订单");
    }
    Order order = new Order();
    order.setUserId(user.getId());
    order.setMerchantId(addOrderFormDto.getMerchantId());
    order.setQuotationId(addOrderFormDto.getQuotationId());
    order.setPayment(addOrderFormDto.getPayment());
    order.setRemark(addOrderFormDto.getRemark());
    order.setPostage(addOrderFormDto.getPostage());
    order.setInvoice(addOrderFormDto.getInvoice());
    order.setAddressId(addOrderFormDto.getAddressId());
    PayOrderItemDto payOrderItemDto = new PayOrderItemDto();
    payOrderItemDto.setAskInfos(addOrderFormDto.getAskInfos());
    ServerResponse serverResponse = orderService.submitOrder(order, payOrderItemDto);
    if (serverResponse.isSuccess()) {
      String path = httpServletRequest.getSession().getServletContext().getRealPath("upload");
      String ip = IpUtils.getIpAddr(httpServletRequest);
      Map<String, Object> resultMap = (Map<String, Object>) serverResponse.getData();
      String orderNo = MapUtils.getString(resultMap, "orderNo");
      try {
        return orderService
            .payExcel(addOrderFormDto.getPayment().toString(), path, ip, user.getId(),orderNo);
      } catch (Exception e) {
        return ServerResponse.createBySuccessMessage("支付异常");
      }
    }
    return ServerResponse.createBySuccess();
  }

  @RequestMapping(value = "askOrder.do", method = RequestMethod.POST)
  @ApiOperation("小程序求购生成订单")
  public ServerResponse askOrder(HttpServletRequest httpServletRequest,
      AddOrderFormDto addOrderFormDto) {
    User user = Const.checkUserLogin(httpServletRequest);
    if (user == null) {
      return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(),
          ResponseCode.NEED_LOGIN.getDesc());
    }
    /**
     * 地址校验
     */
    Long addressId = addOrderFormDto.getAddressId();
    if (addressId == null || addressId == 0) {
      return ServerResponse.createByErrorMessage("地址不能为空");
    }
    /**
     * 校验quotation_id是否被多次使用
     * 只要生成订单就不让再次购买
     */
    Integer count = orderService.checkQuotationId(addOrderFormDto.getQuotationId());
    if (count != 0) {
      return ServerResponse.createByErrorMessage("不能重复提交订单");
    }
    NewOrderAskBuyPayDto newOrderAskBuyPayDto = new NewOrderAskBuyPayDto();
    newOrderAskBuyPayDto.setQuotationId(addOrderFormDto.getQuotationId());
    newOrderAskBuyPayDto.setUserId(user.getId());
    newOrderAskBuyPayDto.setAddressId(addOrderFormDto.getAddressId());
    newOrderAskBuyPayDto.setInvoice(addOrderFormDto.getInvoice());
    newOrderAskBuyPayDto.setRemark(addOrderFormDto.getRemark());
    try {
      return newOrderService.askBuyPay(newOrderAskBuyPayDto, httpServletRequest, user);
    } catch (Exception e) {
      e.printStackTrace();
    }
    return ServerResponse.createByErrorMessage("支付失败");
  }


  @ApiOperation("支付宝回调")
  @RequestMapping(value = "alipay_callback.do", method = RequestMethod.POST)
  public Object alipayCallback(HttpServletRequest request) {
    Map<String, String> params = Maps.newHashMap();
    Map requestParams = request.getParameterMap();
    for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
      String name = (String) iter.next();
      String[] values = (String[]) requestParams.get(name);
      String valueStr = "";
      for (int i = 0; i < values.length; i++) {
        valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
      }
      params.put(name, valueStr);
    }
    log.info("支付宝回调,sign:{},trade_status:{},参数:{}", params.get("sign"), params.get("trade_status"),
        params.toString());

    //非常重要,验证回调的正确性,是不是支付宝发的.并且呢还要避免重复通知.

    params.remove("sign_type");
    try {
      boolean alipayRSACheckedV2 = AlipaySignature
          .rsaCheckV2(params, Configs.getAlipayPublicKey(), "utf-8", Configs.getSignType());

      if (!alipayRSACheckedV2) {
        return ServerResponse.createByErrorMessage("非法请求,验证不通过,再恶意请求我就报警找网警了");
      }
    } catch (AlipayApiException e) {

      log.error("支付宝验证回调异常", e);
    }

    //todo 验证各种数据
    ServerResponse serverResponse = null;
    try {
      serverResponse = orderService.aliCallback(params);
    } catch (Exception e) {
      return Const.AlipayCallback.RESPONSE_FAILED;
    }
    if (serverResponse.isSuccess()) {
      return Const.AlipayCallback.RESPONSE_SUCCESS;
    }
    return Const.AlipayCallback.RESPONSE_FAILED;
  }

  @ApiOperation("查询订单支付状态")
  @RequestMapping(value = "query_order_pay_status.do", method = RequestMethod.POST)
  public ServerResponse<Boolean> queryOrderPayStatus(HttpServletRequest httpServletRequest,
      @ApiParam("订单号") @RequestParam String orderNo) {
    User user = Const.checkUserLogin(httpServletRequest);
    if (user == null) {
      return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(),
          ResponseCode.NEED_LOGIN.getDesc());
    }

    ServerResponse serverResponse = orderService.queryOrderPayStatus(user.getId(), orderNo);
    if (serverResponse.isSuccess()) {
      return ServerResponse.createBySuccess(true);
    }
    return ServerResponse.createBySuccess(false);
  }

    @ApiOperation("前台-商品详情-购买")
    @RequestMapping(value = "addOrder.do", method = RequestMethod.POST)
    public ServerResponse addOrder(HttpServletRequest httpServletRequest, Order order,
                                   PayOrderItemDto payOrderItemDto) {
        /**
         * 地址校验
         */
        Long addressId = order.getAddressId();
        if (addressId == null || addressId == 0) {
            return ServerResponse.createByErrorMessage("地址不能为空");
        }
        User user = Const.checkUserLogin(httpServletRequest);
        if (user == null) {
            return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(),
                    ResponseCode.NEED_LOGIN.getDesc());
        }
        order.setUserId(user.getId());
      Long userIdByProductId = productService.getUserIdByProductId(payOrderItemDto.getProductId());
      if(user.getId().equals(userIdByProductId)){
        return ServerResponse.createByErrorMessage("不能购买自己的商品");
      }
      return orderService.addOrder(order, payOrderItemDto);

    }
    /**
     * @return com.hxgz.steel.common.ServerResponse
     * @author wukeke
     * @creed: 吴先生很快乐
     * @date 2019/2/22 0022 上午 9:38
     */
    @ApiOperation("微信支付接口")
    @RequestMapping(value = "wxPay.do", method = RequestMethod.POST)
    public ServerResponse wxPay(@ApiParam("商家id") @RequestParam String merchantId,
                                @ApiParam("实单求购id") @RequestParam String quotationId,
                                @ApiParam("地址id") @RequestParam String addressId,
                                @ApiParam("是否开发票 0不开发票 1开发票") @RequestParam Integer invoice,
                                @ApiParam("备注") @RequestParam String remark,
                                HttpServletRequest request,
                                HttpServletResponse response)
            throws Exception {
        User user = Const.checkUserLogin(request);
        if (user == null) {
            return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(),
                    ResponseCode.NEED_LOGIN.getDesc());
        }
        String ip = IpUtils.getIpAddr(request);
        return orderService.wxPay(user.getId(), merchantId, quotationId, addressId, invoice, remark, ip,
                response);

  }


}
